package gerado_Csharp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import tools.IOArquivo;

import bean.MetodosServicos;
import br.ufrn.plugin.pewsrt.preferences.PreferenceConstants;

public class GeradorCSharp {
	
	String local;
	private List<MetodosServicos> listMetodosServico;	
	private List<MetodosServicos> listMetodosPartialClass;
	private List<String> servicosIstanciados;
	private List<String> ifElseConditions;
	private List<String> whileConditions;
	StringBuilder sb;
	StringBuilder constantes;
	StringBuilder logWfc;
	
	
	public GeradorCSharp(String local,	List<MetodosServicos> listMetodosServico, List<MetodosServicos> listMetodosPartialClass, StringBuilder constantes, List<String> ifElseCondition, List<String> whileCondition) {
		super();
		this.local 						= local;
		this.listMetodosServico 		= listMetodosServico;
		this.listMetodosPartialClass 	= listMetodosPartialClass;
		this.sb 						= new StringBuilder();
		this.logWfc						= new StringBuilder();
		this.servicosIstanciados		= new ArrayList<String>();
		this.constantes 				= constantes;
		this.ifElseConditions 			= ifElseCondition;
		this.whileConditions 			= whileCondition;
	}

	public void gerarClassMain(){
		inicioDaClasse();
		instanciarServicos();
		partialClass();
		gerarClassesParaAsOperacoes();
		try {
			IOArquivo.salvarArquivo("demo.cs", this.sb.toString());
		} catch (IOException e) {
			System.out.println("Arquivo nao foi encontrado" + e.getMessage());
		}
	}
	
	public void inicioDaClasse(){
		sb.append("using System; \nusing System.Threading; \nusing System.Workflow.Activities; " +
				"\nusing System.Workflow.Runtime; \n \nnamespace FooBar \n{\n" +
				"   class Hello \n" +
				"   { \n" +
				"      public static void Main()\n" +	"      {\n" +
				"         using (WorkflowRuntime workflowRuntime = new WorkflowRuntime()) \n" + "         {\n" +
				"            AutoResetEvent waitHandle = new AutoResetEvent(false);" +	"\n \n" +
				"            workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedE" +
				"ventArgs e) \n" +
				"            { \n               waitHandle.Set();\n            }; \n \n" +
				"            WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(FooBar.Demo)); \n" +
				"            instance.Start(); \n            waitHandle.WaitOne(); \n         }\n      }\n   }\n");
			
	}
	
	public void instanciarServicos(){
		this.sb.append("   partial class Demo\n   {\n");
		this.sb.append(this.constantes.toString());
		
		getInstanciaServicosWeb();
		this.sb.append("\n \n");
				
	}

	public void partialClass(){
		//initVarClass initVar= new initVarClass(); 
		// initVar
		int cont = 0;
		for (MetodosServicos m : this.listMetodosPartialClass) {
			String alias = m.getMetodo();
			MetodosServicos metodo = getMetodo(alias);
			String servicoA = metodo.getMetodo();
			String nome =  m.getMetodo();
			this.sb.append("\t\tprivate void " + nome + cont + "_ExecuteCode" +"(object sender, EventArgs e) { \n");
			if(!m.getSaida().isEmpty()){
				this.sb.append("\t\t\t" + m.getSaida() + " = " + servicoA + "."+ servicoA + "("+ m.getEntrada() +");");	
				this.sb.append("\n\t\t\tConsole.WriteLine(" + m.getSaida()+"); \n");
				this.sb.append(" \t\t} \n");
			} else {
				this.sb.append("\t\t\t"  + servicoA + "."+ servicoA + "("+ m.getEntrada() +"); \n\t\t}\n");	
			}
			cont++;
		}
		
		condicoesIf();
		condicoesWhile();
		
		this.sb.append("\t\tprivate void finalizar_ExecuteCode" +"(object sender, EventArgs e) { \n"
				+ "\t\t\tConsole.WriteLine(\"Tecle Enter para sair: \"); \n " 
				+" \t\t\tConsole.ReadLine();\n\t\t");
		this.sb.append("}\n\t}\n}");
		
	}
	
	public MetodosServicos getMetodo(String nome){
		for (MetodosServicos m : this.listMetodosServico) {
			String a = m.getAlias();
			if(m.getAlias().equalsIgnoreCase(nome)){
				return m;
			}
		}
		
		return null;
	}
	
	public void condicoesWhile(){
		for(int i=0; i<this.whileConditions.size(); i++){
			this.sb.append("\t\tprivate void WhileActivity"+i+"_CodeCondition(object sender, ConditionalEventArgs e)\n\t\t{\n");
			this.sb.append("\t\t\tif (" + this.whileConditions.get(i) +")");
			this.sb.append("\n\t\t\t\te.Result = true;");
			this.sb.append("\n\t\t\telse \n\t\t\t{");
			this.sb.append("\n\t\t\t\te.Result = false; \n\t\t\t\tConsole.Read();\n\t\t\t}\n\t\t}\n\n");
		}
	}
	
	public void condicoesIf(){
		for(int i=0; i<this.ifElseConditions.size();i++){
				this.sb.append(
						"\t\tprivate void IfElseCondition" + i +"_ExecuteCode(object sender, ConditionalEventArgs e) \n \t\t{ \n " +
						"\t\t\tif (" + this.ifElseConditions.get(i) + ") \n" +
						"\t\t\t\te.Result = true; \n" +
						"\t\t\telse \n" +
						"\t\t\t\te.Result = false; \n\t\t}\n"
						);
				
				
				for (MetodosServicos m : this.listMetodosServico) {
					if(this.ifElseConditions.get(i).equalsIgnoreCase(m.getMetodo())){
						this.sb.append(
								"\t\tprivate void IfCondition" + i +"_ExecuteCode(object sender, EventArgs e)" +
								"\n\t\t{\n");
						if(!m.getRetorno().isEmpty()){
							this.sb.append("\t \t \t Console.WriteLine(");
							this.sb.append(m.getServico().toLowerCase().substring(0, m.getServico().length()-7) + "."+ m.getMetodo() + 
									"("+ m.getArgumentosTipos() +")");	
							this.sb.append("); \n\t \t} \n");
						} else {
							this.sb.append("\t \t \t " + m.getServico().toLowerCase().substring(0, m.getServico().length()-7) + "."+ m.getMetodo() + 
									"("+ m.getArgumentosTipos() +");\n"+
									" \t \t } \n");	
						}						
					}						
				}
		}
	};
	
	public void wcf(Set<String> arquivosCS){
		String pasta = System.getProperty("user.dir") + "\\Workflow\\";
		String line;
		System.out.println(pasta); 
		StringBuilder arquivos = new StringBuilder();
		this.setLogWfc(new StringBuilder());
		
		try {  
	        for (String chave : arquivosCS) {  
	        	arquivos.append(" " + pasta + chave + ".cs ");
	        }          
	        
	        /*String comando = "C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0A\\Bin\\WFC.exe "
		    		+ "/target:exe /out:"+ pasta +"demo.exe" +" /r:System.Xml.dll"
	        		+ arquivos.toString() + IOArquivo.arquivosGerados(); 	*/
	        
	        String comando = PreferenceConstants.WCF_PATH
		    		+ " /target:exe /out:"+ pasta +"demo.exe" +" /r:System.Xml.dll"
	        		+ arquivos.toString() + IOArquivo.arquivosGerados(); 
	        System.out.println("WFC.exe " + comando);    
		    Process processo = Runtime.getRuntime().exec(comando);    
		    
		    BufferedReader input = new BufferedReader (new InputStreamReader(processo.getInputStream()));   
		    while ((line = input.readLine()) != null) {  
		    	if(line!=" "){
			    	this.logWfc.append(line);
		    	}
		    }	    
		    
		    input.close();
		    processo.destroy();    
		    IOArquivo.msgLog(this.getLogWfc());
			
			IOArquivo.setArquivosSalvos(new ArrayList<String>());
		}  catch (IOException e)  {  
		   System.out.println("Erro: "+e.getMessage()+"\n"+e.getCause());     
		} finally {
			IOArquivo.msgLog("terminou");
			Runtime.getRuntime().runFinalization();
		}
		
		
		/*C:\Users\Hand\Documents\Visual Studio 2008\GeradorWorkflow\Workflow>wfc /target:
			exe /r:System.Xml.dll demo.xoml demo.cs PortalArtistas.cs*/
	}
	
	public void getInstanciaServicosWeb(){
		for (MetodosServicos m : this.listMetodosServico) {
			sb.append("\t\t" + m.getMetodo() +"Class " + m.getMetodo() + "= new " + m.getMetodo() +"Class(); \n");
		}
	}

	public void gerarClassesParaAsOperacoes(){		
		for (MetodosServicos m : this.listMetodosServico){
			System.out.println("Metodo: " + m.getMetodo() + " Servico: " +m.getServico() + " Retorno: " + m.getRetorno());
			StringBuilder sb = new StringBuilder();
			sb.append("using System; \nusing System.Collections.Generic; \nusing System.Text;" +
					"\nnamespace FooBar \n{" +
					"\n\tpublic class ");
			sb.append(m.getMetodo() + "Class\n\t{\n");
			sb.append("\t \t" + m.getServico() + " " + m.getServico().toLowerCase() + " = new " + m.getServico() + "();  \n");
			//PortalMusicaService portalmusica = new PortalMusicaService();
			
			sb.append("\n\t\tDateTime _termTime;\n" +
					"\t\tpublic DateTime termtime\n\t\t{\n" +
					"\t\t\tget { return _termTime; }\n" +
					"\t\t\tset { _termTime = value; }\n\t\t}\n\n");
			
			sb.append("\t\tDateTime _reqTime;\n" +
					"\t\tpublic DateTime reqtime\n\t\t{\n" +
					"\t\t\tget { return _reqTime; }\n" +
					"\t\t\tset { _reqTime = value; }\n\t\t}\n\n");
			
			sb.append("\t\tDateTime _actTime;\n" +
					"\t\tpublic DateTime acttime\n\t\t{\n" +
					"\t\t\tget { return _actTime; }\n" +
					"\t\t\tset { _actTime = value; }\n\t\t}\n\n");
			
			sb.append("\t\tint _termVal = 0;\n" +
					"\t\tpublic int termval\n\t\t{\n" +
					"\t\t\tget { return _termVal; }\n" +
					"\t\t\tset { _termVal += value; }\n\t\t}\n\n");
			
			sb.append("\t\tint _reqVal = 0;\n" +
					"\t\tpublic int reqval\n\t\t{\n" +
					"\t\t\tget { return _reqVal; }\n" +
					"\t\t\tset { _reqVal += value; }\n\t\t}\n\n");
			
			sb.append("\t\tint _actVal = 0;\n" +
					"\t\tpublic int actval\n\t\t{\n" +
					"\t\t\tget { return _actVal; }\n" +
					"\t\t\tset { _actVal += value; }\n\t\t}\n\n");

			if(m.getRetorno().isEmpty()){
				sb.append("\t\tpublic " + m.getRetorno() + " " + m.getMetodo() +"(" + m.getArgumentosTipos() + ")\n\t\t{\n" +
						"\t\t\tacttime = DateTime.Now;\n" +
						"\t\t\tactval = 1;\n" +
						"\t\t\t" + m.getRetorno() + " retorno = " + m.getServico().toLowerCase() + "."  + m.getMetodo() +"(" + m.getArgumentosSemTipo() + ");\n" + 
						"\t\t\ttermtime = DateTime.Now;\n" +
						"\t\t\ttermval = 1;\n" +
						"\t\t\treturn retorno;\n\t\t}"						
						);
	            
			} else {
				sb.append("\t\tpublic void " + m.getMetodo() +"(" + m.getArgumentosTipos() + ")\n\t\t{\n" +
						"\t\t\tacttime = DateTime.Now;\n" +
						"\t\t\tactval = 1;\n" +
						"\t\t\t" + m.getServico().toLowerCase() + "."  + m.getMetodo() +"(" + m.getArgumentosSemTipo() + ");\n" + 
						"\t\t\ttermtime = DateTime.Now;\n" +
						"\t\t\ttermval = 1;\n\t\t}"					
						);
			}
			sb.append("\n\t}\n}");
			try {
				IOArquivo.salvarArquivo(m.getMetodo() +"Class.cs",  sb.toString());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public String getLogWfc() {
		return logWfc.toString();
	}

	public void setLogWfc(StringBuilder logWfc) {
		this.logWfc = logWfc;
	}
	
	
				
}
